#include "database_table.h"
#include "ui_database_table.h"

database_table::database_table(QWidget *parent)
    : QWidget(parent), ui(new Ui::database_table)
{
    ui->setupUi(this);
    setAttribute(Qt::WA_StyledBackground); // 这句不加,样式表是加载不出来的

    menuWidth = ui->widget_config->width() + 5;
    // 修改后代码增加物理文件存在性检测
    if (QSqlDatabase::contains("sqliteTemp_test"))
    {
        sqlDataBase = QSqlDatabase::database("sqliteTemp_test");
        qDebug() << "Connection exists";
    }
    else
    {
        sqlDataBase = QSqlDatabase::addDatabase("QSQLITE", "sqliteTemp_test");
        // 增加物理文件检测
        if (QFile::exists(dbPath))
        {
            qDebug() << "Database file exists"; // 物理文件已存在
        }
        else
        {
            qDebug() << "Creating new database"; // 物理文件不存在
        }

        sqlDataBase.setDatabaseName(dbPath);

        // 可选：立即创建空文件（如需立刻生成）
        if (!sqlDataBase.open())
        {
            qDebug() << "DB creation error:" << sqlDataBase.lastError();
        }
        else
        {
            sqlDataBase.close();
        }
    }
    if (!sqlDataBase.open())
    {
        qWarning() << "Failed to open database:" << sqlDataBase.lastError().text();
    }
    initializeDatabaseStructure(); // 初始化数据库结构信息
    init_wavepage();
    // 默认第一次展示历史数据的table展示
    ui->stackedWidget_dis->setCurrentWidget(ui->page_table_2);
    ui->widget_find->setEnabled(true);
    ui->widget_chart->setEnabled(false);

    ui->dateTimeEdit_table_start->setDateTime(QDateTime::currentDateTime().addDays(-1));
    ui->dateTimeEdit_table_start->setDisplayFormat("yyyy-MM-dd HH:mm:ss");
    ui->dateTimeEdit_table_end->setDateTime(QDateTime::currentDateTime());
    ui->dateTimeEdit_table_end->setDisplayFormat("yyyy-MM-dd HH:mm:ss");

    // 设置三个通道的默认颜色
    ui->tb_channal1_color->setStyleSheet("background-color: yellow");
    ui->tb_channal2_color->setStyleSheet("background-color: green");
    ui->tb_channal3_color->setStyleSheet("background-color: red");

    // 隐藏第四个通道（如果你有第四个）
    ui->tb_channal4_color->setVisible(false);
    ui->ckb_channal4->setVisible(false);
    ui->cb_channal4_param->setVisible(false);

    ui->checkWidget->setVisible(false);
    ui->buttonWidget->setVisible(false);
    // 在构造函数中添加图标
    addIconToToolButton(ui->tb_channal1_color, "./icon/下箭头.png");
    addIconToToolButton(ui->tb_channal2_color, "./icon/下箭头.png");
    addIconToToolButton(ui->tb_channal3_color, "./icon/下箭头.png");
    on_pb_dis_clicked(); // 开机隐藏左侧图表配置界面
    // 初始化上次存储时间为无效时间
    lastStorageTime = QDateTime();
}

database_table::~database_table()
{
    delete ui;
}
void database_table::initializeDatabaseStructure()
{
    if (!sqlDataBase.isOpen())
    {
        qWarning() << "Database is not open!";
        return;
    }

    database_existing_tables.clear();

    // 获取所有表名
    QStringList tableNames = sqlDataBase.tables(QSql::Tables);

    // 遍历每个表，获取列信息
    for (const QString &tableName : tableNames)
    {
        QSqlRecord record = sqlDataBase.record(tableName);
        QStringList columns;

        for (int i = 0; i < record.count(); ++i)
        {
            columns.append(record.fieldName(i));
        }

        database_existing_tables.insert(tableName, columns);
        qDebug() << "Found existing table:" << tableName << "with columns:" << columns;
    }
}
void database_table::keyPressEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Control)
    {
        qDebug() << "Ctrl key pressed";
        m_dataCustomplot->axisRect()->setRangeZoom(Qt::Vertical); // 设置Y轴缩放
        // ui->Serial_Wave_Zoom->setText(tr("Y轴缩放"));
    }
}

void database_table::keyReleaseEvent(QKeyEvent *event)
{
    if (event->key() == Qt::Key_Control)
    {
        qDebug() << "Ctrl key released";
        m_dataCustomplot->axisRect()->setRangeZoom(Qt::Horizontal); // 设置X轴缩放
        // ui->Serial_Wave_Zoom->setText(tr("X轴缩放"));
    }
}

void database_table::timerEvent(QTimerEvent *event)
{
    Q_UNUSED(event);
    if (event->timerId() == refreshTimer) // 动态加载数据
    {
        bool hasData = false;

        for (auto it = curve_store_map.begin(); it != curve_store_map.end(); ++it)
        {
            STRUCT_DATA_QUEUE &val = it.value();
            if (!val.data.isEmpty())
            {
                QDateTime datetime_st = val.dateTime.dequeue();
                auto xData = datetime_st.toSecsSinceEpoch();

                // 记录第一批数据的时间戳
                if (firstTimestamp == 0)
                {
                    firstTimestamp = xData;
                }

                // 格式化y数据为一位小数
                QString dataStr = val.data.dequeue().toString();
                bool isNumber;
                double yData = dataStr.toDouble(&isNumber);
                if (isNumber)
                {
                    yData = QString::number(yData, 'f', 1).toDouble(); // 格式化为一位小数
                }

                m_dataCustomplot->graph(it.key())->addData(xData, yData);
                hasData = true;
            }
        }

        // 只有在有新数据时才更新X轴范围和重绘
        if (hasData)
        {
            // 如果当前时间与第一批数据时间差小于100秒，则显示从第一批数据开始的100秒范围
            // 否则显示最近100秒的数据范围
            QDateTime currentDateTime = QDateTime::currentDateTime();
            qint64 currentTimestamp = currentDateTime.toSecsSinceEpoch();

            if (currentTimestamp - firstTimestamp < 100)
            {
                // 初始阶段：显示从第一批数据开始的100秒
                m_dataCustomplot->xAxis->setRange(firstTimestamp, firstTimestamp + 100);
            }
            else
            {
                // 数据超过100秒后：始终显示最近100秒的数据
                m_dataCustomplot->xAxis->setRange(currentTimestamp - 100, currentTimestamp);
            }

            m_dataCustomplot->yAxis->rescale(true);
            m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot);
        }
    }
}
void database_table::init_customplotStyleSheet()
{
    // 设置背景
    m_dataCustomplot->setBackground(QBrush(QColor(28, 46, 90)));
    m_dataCustomplot->axisRect()->setBackground(QBrush(QColor(28, 46, 90)));
    // 设置坐标轴
    m_dataCustomplot->xAxis->setBasePen(QPen(Qt::white, 4));
    m_dataCustomplot->yAxis->setBasePen(QPen(Qt::white, 4));
    m_dataCustomplot->xAxis->grid()->setSubGridPen(QPen(QColor(50, 50, 50), 1, Qt::DotLine)); // 网格浅色点线
    m_dataCustomplot->yAxis->grid()->setSubGridPen(QPen(QColor(50, 50, 50), 1, Qt::DotLine)); // 网格浅色点线
    m_dataCustomplot->xAxis->grid()->setSubGridVisible(true);                                 // 显示x轴子网格线
    m_dataCustomplot->yAxis->grid()->setSubGridVisible(true);                                 // 显示要轴子网格线
    m_dataCustomplot->xAxis->grid()->setZeroLinePen(QPen(Qt::white));                         // x轴0线颜色白色
    m_dataCustomplot->yAxis->grid()->setZeroLinePen(QPen(Qt::white));                         // y轴0线颜色白色

    // 刻度线
    QPen pen;
    pen.setColor(Qt::white); // 主刻度红色
    pen.setWidth(2);         // 线宽2
    m_dataCustomplot->xAxis->setTickPen(pen);
    m_dataCustomplot->xAxis->setTickLengthIn(30);  // 主刻度向内延伸30
    m_dataCustomplot->xAxis->setTickLengthOut(10); // 主刻度向外延伸10
    pen.setColor(Qt::white);                       // 子刻度蓝色
    m_dataCustomplot->xAxis->setSubTickPen(pen);
    // m_dataCustomplot->xAxis->setSubTickLengthIn(15); // 子刻度向内延伸15
    // m_dataCustomplot->xAxis->setSubTickLengthOut(5); // 子刻度向外延伸5

    // // 设置坐标轴
    // m_dataCustomplot->xAxis->setBasePen(QPen(Qt::white, 1));
    // m_dataCustomplot->yAxis->setBasePen(QPen(Qt::white, 1));
    // m_dataCustomplot->xAxis->setTickPen(QPen(Qt::white, 1));
    // m_dataCustomplot->yAxis->setTickPen(QPen(Qt::white, 1));
    // m_dataCustomplot->xAxis->setSubTickPen(QPen(QColor(176, 176, 176), 1));
    // m_dataCustomplot->yAxis->setSubTickPen(QPen(QColor(176, 176, 176), 1));

    // // 设置标签颜色
    // m_dataCustomplot->xAxis->setLabelColor(Qt::white);
    // m_dataCustomplot->yAxis->setLabelColor(Qt::white);
    // m_dataCustomplot->xAxis->setTickLabelColor(Qt::white);
    // m_dataCustomplot->yAxis->setTickLabelColor(Qt::white);

    // // 设置网格
    // m_dataCustomplot->xAxis->grid()->setPen(QPen(QColor(0, 163, 255, 100), 1, Qt::DotLine));
    // m_dataCustomplot->yAxis->grid()->setPen(QPen(QColor(0, 163, 255, 100), 1, Qt::DotLine));
    // m_dataCustomplot->xAxis->grid()->setSubGridPen(QPen(QColor(0, 163, 255, 50), 1, Qt::DotLine));
    // m_dataCustomplot->yAxis->grid()->setSubGridPen(QPen(QColor(0, 163, 255, 50), 1, Qt::DotLine));

    // // 设置图例
    // m_dataCustomplot->legend->setVisible(true);
    // m_dataCustomplot->legend->setBrush(QColor(28, 63, 125, 200));
    // m_dataCustomplot->legend->setBorderPen(QPen(QColor(0, 163, 255)));

    m_dataCustomplot->xAxis->setBasePen(QPen(Qt::white, 1));    // 轴线的画笔
    m_dataCustomplot->xAxis->setTickPen(QPen(Qt::white, 1));    // 轴刻度线的画笔
    m_dataCustomplot->xAxis->setSubTickPen(QPen(Qt::white, 1)); // 轴子刻度线的画笔
    m_dataCustomplot->xAxis->setTickLabelColor(Qt::white);      // 轴刻度文字颜色
    // m_dataCustomplot->xAxis->setLabel("时间");                            // 只有设置了标签，轴标签的颜色才会显示
    m_dataCustomplot->xAxis->setLabelColor(Qt::white);                    // 轴标签颜色
    m_dataCustomplot->xAxis->setTickLengthIn(3);                          // 轴线内刻度的长度
    m_dataCustomplot->xAxis->setTickLengthOut(5);                         // 轴线外刻度的长度
    m_dataCustomplot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow); // 设置轴线结束时的风格为 实角三角形但内部有凹陷的形状， setLowerEnding设置轴线开始时的风格

    m_dataCustomplot->yAxis->setBasePen(QPen(Qt::white, 1));    // 轴线的画笔
    m_dataCustomplot->yAxis->setTickPen(QPen(Qt::white, 1));    // 轴刻度线的画笔
    m_dataCustomplot->yAxis->setSubTickPen(QPen(Qt::white, 1)); // 轴子刻度线的画笔

    m_dataCustomplot->yAxis->setTickLabelColor(Qt::white); // 轴刻度文字颜色
    // m_dataCustomplot->yAxis->setLabel("时间");                            // 只有设置了标签，轴标签的颜色才会显示
    m_dataCustomplot->yAxis->setLabelColor(Qt::white);                    // 轴标签颜色
    m_dataCustomplot->yAxis->setTickLengthIn(3);                          // 轴线内刻度的长度
    m_dataCustomplot->yAxis->setTickLengthOut(5);                         // 轴线外刻度的长度
    m_dataCustomplot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow); // 设置轴线结束时的风格为 实角三角形但内部有凹陷的形状， setLowerEnding设置轴线开始时的风格
}

/**
 * @brief database_table::Init_wavepage
 */
void database_table::init_wavepage()
{
    m_dataCustomplot = new MyCustomPlot();
    ui->stackedWidget_dis->addWidget(m_dataCustomplot);
    curve_store_map.clear(); /*清空曲线记录*/
    /*ui空间默认设置*/
    // ui->ckb_dis_point->setChecked(false);         /*默认不显示游标*/
    m_dataCustomplot->xAxis->setTickLabels(true); // 显示刻度标签
    // m_dataCustomplot->xAxis->setNumberFormat("gbc");//g灵活的格式,b漂亮的指数形式，c乘号改成×
    m_dataCustomplot->xAxis->setNumberPrecision(1);                                        // 精度1
    m_dataCustomplot->xAxis->ticker()->setTickCount(7);                                    // 设置7个主刻度
    m_dataCustomplot->xAxis->ticker()->setTickStepStrategy(QCPAxisTicker::tssReadability); // 可读性优于设置
    m_dataCustomplot->xAxis->setUpperEnding(QCPLineEnding::esSpikeArrow);                  // x轴终点箭头图案
    m_dataCustomplot->xAxis->setLowerEnding(QCPLineEnding::esDisc);                        // x轴起点圆点图案

    m_dataCustomplot->xAxis2->setVisible(false); // 不显示x轴2

    m_dataCustomplot->yAxis2->setVisible(false); // 不显示y轴2
    init_customplotStyleSheet();
    m_dataCustomplot->yAxis->setUpperEnding(QCPLineEnding::esSpikeArrow); // y轴终点小方块图案

    // 添加层
    m_dataCustomplot->plotLayout()->insertRow(0);

    // 设置图例属性
    m_dataCustomplot->legend->setVisible(true);

    // 设置图例为水平布局并居中
    QCPLegend *legend = m_dataCustomplot->legend;
    legend->setFillOrder(QCPLegend::foColumnsFirst);
    legend->setColumnSpacing(20);
    legend->setRowSpacing(0);
    // 设置图例外边距，左右各留出一定距离
    legend->setMargins(QMargins(300, 5, 300, 5)); // 左、上、右、下边距，左右各20像素
    // 通过设置图例的最小大小来确保图例不会占满整个宽度
    legend->setMinimumSize(100, 30);
    // 将图例添加到顶部
    m_dataCustomplot->plotLayout()->addElement(0, 0, legend);
    m_dataCustomplot->plotLayout()->setRowStretchFactor(0, 0.001);

    m_dataCustomplot->legend->setSelectableParts(QCPLegend::spItems); // 设置legend只能选择图例

    /*设置图例透明度*/
    m_dataCustomplot->legend->setBrush(QBrush(QColor(255, 255, 255, 0))); // 设置图例画刷颜色
    m_dataCustomplot->legend->setTextColor(Qt::white);
    m_dataCustomplot->legend->setBorderPen(Qt::NoPen); // 设置图例边框为不显示

    /*设置交互模式*/
    m_dataCustomplot->setInteractions(QCP::iRangeDrag                                 // 可平移
                                      | QCP::iRangeZoom                               // 可滚轮缩放
                                      | QCP::iSelectLegend | QCP::iSelectPlottables); // 可选中图例

    // m_dataCustomplot->addGraph(m_dataCustomplot->xAxis, m_dataCustomplot->yAxis);

    /*游标设计*/
    plotTracer = new QCPItemTracer(m_dataCustomplot); /*实例化游标*/
    plotTracer->setStyle(QCPItemTracer::tsCrosshair); /*设置游标样式*/
    plotTracer->setBrush(Qt::white);                  /*设置游标颜色*/
    plotTracer->setInterpolating(false);              /*不允许游标插值*/
    plotTracer->setPen(QPen(Qt::DashLine));           /*虚线游标*/
    plotTracer->setVisible(true);                     // 游标永远显示

    /*游标标签*/
    m_dataCustomplot->setMouseTracking(true);
    plotText = new QCPItemText(m_dataCustomplot); /*实例化游标标签*/
    plotText->setLayer("overlay");
    plotText->setPen(QPen(Qt::white)); /*文本画笔颜色*/
    plotText->setBrush(Qt::cyan);
    // plotText->setPadding(QMargins(2,2,2,2));/*设置文本边距*/
    plotText->setPositionAlignment(Qt::AlignLeft | Qt::AlignTop);  /*设置文本位置*/
    plotText->setTextAlignment(Qt::AlignLeft);                     /*设置文本对齐方式*/
    plotText->position->setType(QCPItemPosition::ptAxisRectRatio); // 设置文本位置类型
    // 下面这个语句很重要，它将游标说明锚固在tracer位置处，实现自动跟随
    plotText->position->setParentAnchor(plotTracer->position);
    plotText->setVisible(true); // 游标永远显示

    tracerGraph = NULL;
    connect(m_dataCustomplot, &QCustomPlot::mouseMove, this, [=](QMouseEvent *event)
            {
                double x = m_dataCustomplot->xAxis->pixelToCoord(event->pos().x());
                if (!tracerEnable || NULL == tracerGraph)
                {
                    plotTracer->setGraph(NULL);
                    return;
                }
                plotTracer->setGraph(tracerGraph);   // 设置游标吸附于指定曲线
                plotTracer->setGraphKey(x);          // 将游标横坐标（key）设置成刚获得的横坐标数据x
                plotTracer->setInterpolating(false); // 游标的纵坐标可以通过曲线数据线性插值自动获得
                plotTracer->updatePosition();        // 使得刚设置游标的横纵坐标位置生效
                // 以下代码用于更新游标说明的内容
                double xValue = plotTracer->position->key();
                QDateTime datetime = QDateTime::fromSecsSinceEpoch(xValue);       // 转换回 QDateTime
                QString formattedTime = datetime.toString("yyyy/MM/dd HH:mm:ss"); // 格式化时间
                double yValue = plotTracer->position->value();

                // 格式化y值为一位小数
                QString formattedYValue = QString::number(yValue, 'f', 1);

                plotText->setText(plotSelectedName + QString("\n时间 = %1\n值 = %2").arg(formattedTime).arg(formattedYValue));
                m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); // 刷新图标，不能省略
            });

    connect(m_dataCustomplot, &QCustomPlot::selectionChangedByUser, this, [=]() mutable
            {
                for (int i = 0; i < m_dataCustomplot->graphCount(); ++i)
                {
                    QCPGraph *graph = m_dataCustomplot->graph(i);
                    QCPPlottableLegendItem *item = m_dataCustomplot->legend->itemWithPlottable(graph);
                    if (item->selected() || graph->selected())//选中了哪条曲线或者曲线的图例
                    {
                        tracerGraph = graph;
                        plotSelectedName = m_dataCustomplot->legend->itemWithPlottable(graph)->plottable()->name(); //获取被选中的曲线的名字
                        tracerEnable = true;

                        /*图例与曲线同时选中*/
                        item->setSelected(true);
                        /*设置选中线的样式*/
                        QPen pen = graph->pen();
                        // QPen pen;
                        pen.setWidth(4);
                        // pen.setColor(curve_store_map.value(i).curve_color);
                        graph->selectionDecorator()->setPen(pen);
                        //注意：这句需要Qcustomplot2.0系列版本
                        graph->setSelection(QCPDataSelection(graph->data()->dataRange()));
                        //这句1.0系列版本即可
                        //graph->setSelected(true);
                    }
                } });

    // 定义一个时间轴格式变量
    //  QSharedPointer<QCPAxisTickerTime> timeTicker(new QCPAxisTickerTime);
    //  // 将X轴设置为时间轴
    //  m_dataCustomplot->xAxis->setTicker(timeTicker);
    QSharedPointer<QCPAxisTickerDateTime> timeTicker(new QCPAxisTickerDateTime);
    // timeTicker->setTickCount(10);                          // 设置刻度数量与主刻度一致
    timeTicker->setDateTimeFormat("yyyy-MM-dd\nhh:mm:ss"); // 日期和时间换行显示，防止过长，显示不下
    m_dataCustomplot->xAxis->setTicker(timeTicker);        // 将x轴设置为日期时间格式，你也可以将xAxis改为yAxis将Y轴设置为日期时间格式

    m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); /*重写绘制图像，QCustomPlot::rpQueuedReplot表示是将该信号放入队列，避免大量数据造成堵塞*/
}

/**
 * @brief database_table::processJsonCommand 解析json
 * @param jsonStr
 */
// database_table.cpp - 修改 processJsonCommand 方法
bool database_table::processJsonCommand(const QString &jsonStr, QString *err)
{
    // qDebug() << jsonStr;
    // 有一种信息不是json格式，而是直接的information信息
    if (jsonStr.contains("information"))
    {
        // 取出information：后面的数据
        QStringList parts = jsonStr.split(":");
        if (parts.size() > 1)
        {
            QString information = parts[1].trimmed(); // trimmed() 用于去除前后空格
            // information 现在包含 "A柜"
            qDebug() << "information:" << information;
            ui->comboBox_select->setCurrentText(information);
        }
        updateBlockInfoLayout();
    }

    // 接收两种json，一种是configjson，另一种是datajson，只更新数据
    // id是所有柜子都不能重复的寄存器地址，在数据库里存储只需要按柜子分开建立多个表，再按id分开，因为id一定是专属的，列标题是该柜子下的所有id。然后最后一列是datatime
    // 当配置更新时，表需要同步更新，但是表不会删除之前已读取的id 的信息，也就是初始化的时候集体新增，后面更换配置后只增加新增列，和新增表，不删除历史东西
    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(jsonStr.toUtf8(), &error);

    if (error.error != QJsonParseError::NoError)
    {
        *err = "JSON analyse failed: " + error.errorString();
        return false;
    }

    QJsonObject root = doc.object();

    if (root.contains("plugin_config"))
    {
        QJsonObject config = root["plugin_config"].toObject();
        QJsonArray blocks = config["blocks"].toArray();
        // 清空之前的映射
        blockParamsMap.clear();
        for (const QJsonValue &blockVal : blocks)
        {
            QJsonObject blockObj = blockVal.toObject();
            QString blockName = blockObj["block_name"].toString();
            QJsonArray params = blockObj["parameters"].toArray();
            QStringList paramsList;
            QList<paramInfo> paramList;
            for (const QJsonValue &paramVal : params)
            {
                QJsonObject paramObj = paramVal.toObject();
                QString param_position = paramObj["position"].toString();
                QString param_id = paramObj["modbusAddr"].toString();
                paramsList << (param_position);
                paramInfo paramInfo;
                paramInfo.position = param_position;
                paramInfo.type = paramObj["type"].toString();
                paramList.append(paramInfo);
            }
            blockParamsMap.insert(blockName, paramList);
            table_list.insert(blockName, paramsList);
        }
        createTablesFromMap();
        // updateBlockInfoLayout();
    }
    else if (root.contains("plugin_data"))
    {
        // 获取当前时间
        QDateTime currentTime = QDateTime::currentDateTime();

        // 检查是否应该存储到数据库（距离上次存储超过10分钟 或者 是第一次存储）
        bool shouldStoreToDB = lastStorageTime.isNull() ||
                               lastStorageTime.msecsTo(currentTime) >= STORAGE_INTERVAL;

        QString timestamp = currentTime.toString("yyyy-MM-dd hh:mm:ss");

        QJsonObject root_data = root["plugin_data"].toObject();
        QJsonArray blocks = root_data["blocks"].toArray();
        for (const QJsonValue &blockVal : blocks)
        {
            QJsonObject blockObj = blockVal.toObject();
            QString blockName = blockObj["block_name"].toString();
            QJsonArray params = blockObj["parameters"].toArray();

            // 查找对应的blockParamsMap条目，将data赋值上去
            if (blockParamsMap.contains(blockName))
            {
                QList<paramInfo> &paramList = blockParamsMap[blockName];

                // 遍历收到的参数数据
                for (const QJsonValue &paramVal : params)
                {
                    QJsonObject paramObj = paramVal.toObject();
                    QString param_position = paramObj["position"].toString();
                    QString param_data = paramObj["data"].toString();

                    // 在paramList中查找匹配的位置
                    for (int i = 0; i < paramList.size(); ++i)
                    {
                        if (paramList[i].position == param_position)
                        {
                            // 更新对应位置的数据
                            paramList[i].data = param_data;
                            break;
                        }
                    }
                }
            }

            QStringList columns_names;
            QStringList columns_datas;
            columns_names << "时间";
            columns_datas << timestamp;
            for (const QJsonValue &paramVal : params)
            {
                QJsonObject paramObj = paramVal.toObject();
                QString param_position = paramObj["position"].toString();
                QString param_id = paramObj["modbusAddr"].toString();
                if (ui->comboBox_select->currentText() == blockName)
                {
                    param_update(paramObj["data"].toString(), param_position);
                }
                columns_names << param_position;
                columns_datas << paramObj["data"].toString();
            }

            // 只有在满足时间条件时才存储到数据库
            if (shouldStoreToDB)
            {
                for (int i = 0; i < columns_names.size(); ++i)
                {
                    columns_names.replace(i, "'" + columns_names.at(i) + "'");
                }

                for (int i = 0; i < columns_datas.size(); ++i)
                {
                    columns_datas.replace(i, "'" + columns_datas.at(i) + "'");
                }
                // qDebug() << "receive data :" << columns_datas;
                QString sql = QString("INSERT INTO '%1' (%2) VALUES (%3)")
                                  .arg(blockName)
                                  .arg(columns_names.join(", "))
                                  .arg(columns_datas.join(", "));
                QSqlQuery query(sqlDataBase);
                query.prepare(sql);

                if (!query.exec())
                {
                    qWarning() << "Insert error:" << query.lastError().text();
                    qDebug() << "SQL:" << sql;
                }
                else
                {
                    // qDebug() << "Successfully inserted data into" << blockName;
                }
            }
        }

        // 如果本次进行了数据库存储，更新最后存储时间
        if (shouldStoreToDB)
        {
            lastStorageTime = currentTime;
        }
    }
    else
    {
        *err = "JSON format error: can not fine plugin_config seg";
        return false;
    }
    updateBlockInfoLayout();
    return true;
}

/**
 * @brief database_table::updateBlockInfoLayout 根据blockParamsMap更新布局控件
 */
void database_table::updateBlockInfoLayout()
{
    // 清空布局内的所有控件
    QLayoutItem *child;
    while ((child = ui->widget_data2->layout()->takeAt(0)) != nullptr)
    {
        QWidget *widget = child->widget();
        if (widget)
        {
            delete widget;
        }
        delete child;
    }

    // 获取当前选择的表名
    QString currentBlockName = ui->comboBox_select->currentText();

    // 检查blockParamsMap中是否存在该表名
    if (!blockParamsMap.contains(currentBlockName))
    {
        qDebug() << "Block name not found in blockParamsMap:" << currentBlockName;
        return;
    }

    // 获取对应的参数列表
    QList<paramInfo> paramList = blockParamsMap[currentBlockName];

    // 确保使用网格布局
    QGridLayout *gridLayout = qobject_cast<QGridLayout *>(ui->widget_data2->layout());
    if (!gridLayout)
    {
        // 如果当前布局不是网格布局，则删除现有布局并创建网格布局
        QLayout *oldLayout = ui->widget_data2->layout();
        if (oldLayout)
        {
            delete oldLayout;
        }
        gridLayout = new QGridLayout(ui->widget_data2);
        gridLayout->setContentsMargins(0, 0, 0, 0);
        gridLayout->setSpacing(5);
        ui->widget_data2->setLayout(gridLayout);
    }
    else
    {
        // 清空现有网格布局
        while ((child = gridLayout->takeAt(0)) != nullptr)
        {
            QWidget *widget = child->widget();
            if (widget)
            {
                delete widget;
            }
            delete child;
        }
    }

    // 固定为6列布局
    const int columns = 12;
    // 计算需要的行数（最多2行）
    const int rows = 1; //(paramList.size() <= 6) ? 1 : 2;

    // 设置widget_data2的高度
    int widgetHeight = rows * 60; // 每行约70像素高度 + 边距
    ui->widget_data2->setMinimumHeight(widgetHeight);

    // 根据参数列表生成datablockinfo控件并插入到网格布局中
    for (int i = 0; i < paramList.size() && i < 12; ++i) // 最多显示12个（2行6列）
    {
        // 创建datablockinfo控件实例
        dataBlockInfo *blockInfoWidget = new dataBlockInfo(this);

        // 设置控件属性
        blockInfoWidget->setUiData(paramList[i]);

        // 计算行和列位置
        int row = i / columns;
        int col = i % columns;

        // 将控件添加到网格布局中
        gridLayout->addWidget(blockInfoWidget, row, col);

        // 设置控件的对齐方式为靠左对齐
        gridLayout->setAlignment(blockInfoWidget, Qt::AlignLeft | Qt::AlignTop);
    }

    for (int i = 0; i < columns; ++i)
    {
        gridLayout->setColumnStretch(i, 1); // 所有列等宽拉伸
    }
}
/**
 * @brief database_table::on_ckb_dis_point_toggled:是否显示游标
 * @param checked
 */
void database_table::on_ckb_dis_point_toggled(bool checked)
{
    plotTracer->setVisible(checked);
    plotText->setVisible(checked);
    m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); // 重绘图像
}
static bool all_unique(int a, int b, int c, int d)
{
    int arr[4] = {a, b, c, d};
    for (int i = 0; i < 4; i++)
    {
        for (int j = i + 1; j < 4; j++)
        {
            if (arr[i] == arr[j])
            {
                return false;
            }
        }
    }
    return true;
}

bool database_table::compareNonEmptyStrings(const QString &str1,
                                            const QString &str2,
                                            const QString &str3)
{
    // 存储非空字符串的临时集合
    QSet<QString> uniqueStrings;

    // 检查第一个字符串
    if (!str1.isEmpty())
    {
        if (uniqueStrings.contains(str1))
            return false; // 发现重复
        uniqueStrings.insert(str1);
    }

    // 检查第二个字符串
    if (!str2.isEmpty())
    {
        if (uniqueStrings.contains(str2))
            return false;
        uniqueStrings.insert(str2);
    }

    // 检查第三个字符串
    if (!str3.isEmpty())
    {
        if (uniqueStrings.contains(str3))
            return false;
        uniqueStrings.insert(str3);
    }

    if (str1.isEmpty() && str2.isEmpty() && str3.isEmpty())
    {
        return false;
    }

    return true; // 所有非空字符串均唯一
}

/**
 * @brief database_table::on_pb_down_set_released:更新设置，同步更新表曲线
 */
void database_table::on_pb_down_set_released()
{

    if (compareNonEmptyStrings(ui->cb_channal1_param->currentText(),
                               ui->cb_channal3_param->currentText(),
                               ui->cb_channal2_param->currentText()))
    {

        /*重写当前设置*/
        // m_dataCustomplot->clearGraphs();
        QMap<QString, int> graph_index;

        STRUCT_DATA_QUEUE curve_data_store;
        curve_data_store.data.clear();
        curve_data_store.plotCounter = 0;
        curve_store_map.clear();
        QPalette palette; // 获取按钮的调色板

        palette = ui->tb_channal1_color->palette();
        curve_data_store.curve_color = palette.color(QPalette::Button);
        curve_data_store.data_type = ui->cb_channal1_param->currentText();
        curve_data_store.is_visiable = ui->ckb_channal1->isChecked();
        // m_dataCustomplot->addGraph();
        // curve_data_store.curveGraph_index = 0;
        curve_store_map.insert(0, curve_data_store);
        graph_index.insert(ui->cb_channal1_param->currentText(), 0);

        palette = ui->tb_channal2_color->palette();
        curve_data_store.curve_color = palette.color(QPalette::Button);
        curve_data_store.data_type = ui->cb_channal2_param->currentText();
        curve_data_store.is_visiable = ui->ckb_channal2->isChecked();
        // m_dataCustomplot->addGraph();
        // curve_data_store.curveGraph_index = 1;
        curve_store_map.insert(1, curve_data_store);
        graph_index.insert(ui->cb_channal2_param->currentText(), 1);

        palette = ui->tb_channal3_color->palette();
        curve_data_store.curve_color = palette.color(QPalette::Button);
        curve_data_store.data_type = ui->cb_channal3_param->currentText();
        curve_data_store.is_visiable = ui->ckb_channal3->isChecked();
        // m_dataCustomplot->addGraph();
        // curve_data_store.curveGraph_index = 2;
        curve_store_map.insert(2, curve_data_store);
        graph_index.insert(ui->cb_channal3_param->currentText(), 2);

        // palette = ui->tb_channal4_color->palette();
        // curve_data_store.curve_color = palette.color(QPalette::Button);
        // curve_data_store.data_type = ui->cb_channal4_param->currentText();
        // curve_data_store.is_visiable = ui->ckb_channal4->isChecked();

        // curve_store_map.insert(3, curve_data_store);
        // graph_index.insert(ui->cb_channal4_param->currentText(), 3);

        update_graph();
        if (ui->radioButton_history->isChecked())
        {
            // 准备 SQL 查询
            QMap<QString, QMap<QDateTime, QVariant>> dataMaps;
            QStringList columns;
            QString text;

            text = ui->cb_channal1_param->currentText();
            if (!text.isEmpty())
            {
                columns << text;
            }

            text = ui->cb_channal2_param->currentText();
            if (!text.isEmpty())
            {
                columns << text;
            }

            text = ui->cb_channal3_param->currentText();
            if (!text.isEmpty())
            {
                columns << text;
            }
            loadDataToMaps(ui->comboBox_select->currentText(), columns, dataMaps);

            // 打印结果
            for (const QString &column : columns)
            {

                int index = graph_index.value(column);

                for (auto it = dataMaps[column].begin(); it != dataMaps[column].end(); ++it)
                {
                    // qDebug() << "Datetime:" << it.key() << "Value:" << it.value();
                    auto xData = it.key().toSecsSinceEpoch();
                    auto yData = it.value().toDouble();
                    m_dataCustomplot->graph(index)->addData(xData, yData);
                }
            }
            on_pb_auto_released(); // 自动更新xy自适应
        }
    }
    else
    {
        // QMessageBox::information(this, "错误提示", "请勾选不同曲线内容|未选择内容!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
    }
}

void database_table::update_graph()
{
    m_dataCustomplot->clearGraphs();
    tracerGraph = NULL;
    tracerEnable = false;
    for (auto it = curve_store_map.begin(); it != curve_store_map.end(); ++it)
    {
        m_dataCustomplot->addGraph();
        STRUCT_DATA_QUEUE val = it.value();
        QPen pen;
        pen.setWidth(2); // 曲线的粗细
        pen.setColor(val.curve_color);
        m_dataCustomplot->graph(it.key())->setPen(pen);              // 曲线颜色设置
        m_dataCustomplot->graph(it.key())->setAntialiasedFill(true); // 设置抗锯齿
        QString graph_name = val.data_type;
        m_dataCustomplot->graph(it.key())->setName(graph_name);         /*设置画布曲线名称*/
        m_dataCustomplot->graph(it.key())->setVisible(val.is_visiable); /*设置是否显示*/

        // qDebug() << it.key() << ": " << it.value();
    }
    m_dataCustomplot->rescaleAxes(true);
    m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); // 重绘图像
}

/**
 * @brief database_table::slot_param_return:读返回数据.入列到对应结构体
 * @param ret_data
 */
void database_table::param_update(QString data, QString data_type)
{
    for (auto it = curve_store_map.begin(); it != curve_store_map.end(); ++it)
    {
        STRUCT_DATA_QUEUE &val = it.value();
        if (val.data_type == data_type)
        {
            // 如果数据是"--"，使用上一个数据点的值（如果有）
            if (data == "--")
            {
                if (!val.data.isEmpty())
                {
                    // 使用队列中最后一个有效值
                    QString lastValidData = val.data.back().toString(); // 添加 toString()
                    qDebug() << "Using last valid data: " << lastValidData;
                    val.data.enqueue(lastValidData);
                }
                else
                {
                    // 如果没有历史数据，则跳过此次更新
                    continue;
                }
            }
            else
            {
                // 正常数据直接入队
                val.data.enqueue(data);
            }

            QDateTime currentDateTime = QDateTime::currentDateTime();
            val.dateTime.enqueue(currentDateTime);
        }
    }
}

/**
 * @brief database_table::tool_button_color_rendering:toolbutton颜色渲染
 * @param tool_button
 */
void database_table::tool_button_color_rendering(QToolButton *tool_button)
{
    QColorDialog *cdia = new QColorDialog(this);
    cdia->setWindowTitle("选择颜色");
    // 获取按钮的调色板
    QPalette palette = tool_button->palette();

    // 获取按钮的背景颜色
    QColor backgroundColor = palette.color(QPalette::Button);
    cdia->setCurrentColor(backgroundColor);
    if (cdia->exec() != QDialog::Accepted)
        return;
    QColor m_color = cdia->currentColor();
    QString qss = QString("background-color: %1").arg(m_color.name());
    tool_button->setStyleSheet(qss);
}

void database_table::on_tb_channal1_color_released()
{
    tool_button_color_rendering(ui->tb_channal1_color);
}

void database_table::on_tb_channal2_color_released()
{
    tool_button_color_rendering(ui->tb_channal2_color);
}

void database_table::on_tb_channal3_color_released()
{
    tool_button_color_rendering(ui->tb_channal3_color);
}

void database_table::on_tb_channal4_color_released()
{
    tool_button_color_rendering(ui->tb_channal4_color);
}

void database_table::on_pb_open_toggled(bool checked)
{

    if (m_dataCustomplot->graphCount() < 3 && checked)
    {
        QMessageBox::information(this, "错误提示", "请更新曲线设置!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
        ui->pb_open->setChecked(false);
        return;
    }

    // is_run_oscill = checked;
    if (checked)
    {
        ui->pb_open->setText("Stop");
        refreshTimer = startTimer(sample_rate);
    }
    else
    {
        ui->pb_open->setText("Start");
        killTimer(refreshTimer);
    }
}

void database_table::on_ckb_auto_dis_x_toggled(bool checked)
{
    is_auto_x_dis = checked;
}
void database_table::on_ckb_auto_dis_y_toggled(bool checked)
{
    is_auto_y_dis = checked;
}

void database_table::on_ckb_channal1_toggled(bool checked)
{
    if (m_dataCustomplot->graphCount() >= 1)
    {
        m_dataCustomplot->graph(0)->setVisible(checked);       /*设置是否显示*/
        m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); // 重绘图像
    }
}

void database_table::on_ckb_channal2_toggled(bool checked)
{
    if (m_dataCustomplot->graphCount() >= 2)
    {
        m_dataCustomplot->graph(1)->setVisible(checked);       /*设置是否显示*/
        m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); // 重绘图像
    }
}

void database_table::on_ckb_channal3_toggled(bool checked)
{
    if (m_dataCustomplot->graphCount() >= 3)
    {
        m_dataCustomplot->graph(2)->setVisible(checked);       /*设置是否显示*/
        m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); // 重绘图像
    }
}

void database_table::on_ckb_channal4_toggled(bool checked)
{
    // if (m_dataCustomplot->graphCount() >= 4)
    // {
    //     m_dataCustomplot->graph(3)->setVisible(checked);       /*设置是否显示*/
    //     m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); // 重绘图像
    // }
}

/**
 * @brief database_table::on_pb_auto_released：一键自适应
 */
void database_table::on_pb_auto_released()
{
    // if (!ui->ckb_auto_dis_x->isChecked() && !ui->ckb_auto_dis_y->isChecked())
    // {
    m_dataCustomplot->xAxis->rescale(true);                // 调整X轴的范围，使之能显示出所有的曲线的X值
    m_dataCustomplot->yAxis->rescale(true);                // 调整Y轴的范围，使之能显示出所有的曲线的Y值
    m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); // 刷新
    // }
    // else
    // {
    //     QMessageBox::information(this, "错误提示", "auto功能必须关闭xy轴的自适应和跟随功能!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
    // }
}

// /**
//  * @brief database_table::on_pb_save_wave_picture_released：截图
//  */
// void database_table::on_pb_save_wave_picture_released()
// {
//     QString fileName = QFileDialog::getSaveFileName(this, "保存截图", "", "Images (*.png *.xpm *.jpg)");
//     if (!fileName.isEmpty())
//     {
//         m_dataCustomplot->savePng(fileName);
//     }
// }

// /**
//  * @brief database_table::on_pb_save_wave_file_released:存储曲线数据
//  */
// void database_table::on_pb_save_wave_file_released()
// {
//     if (tracerGraph == NULL)
//     {
//         QMessageBox::information(this, "错误提示", "请选择需要存储的曲线!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
//         return;
//     }

//     QMap<QString, QString> save_data;
//     for (int j = 0; j < tracerGraph->data()->size(); ++j)
//     {
//         double xPosition = tracerGraph->data()->at(j)->key;
//         double yPosition = tracerGraph->data()->at(j)->value;
//         QString xValue = QString::number(xPosition);
//         QString yValue = QString::number(yPosition);
//         // 处理xValue和yValue
//         save_data.insert(xValue, yValue);
//         qDebug() << xValue << yValue;
//     }

//     if (save_data.isEmpty())
//     {
//         QMessageBox::information(this, "警告提示", "选择的曲线无数据!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
//         return;
//     }

//     QString fileName = QFileDialog::getSaveFileName(this, "保存曲线数据文件", "", "Datas (*.data)");
//     if (!fileName.isEmpty())
//     {
//         GeneralFunc::generateIniFile(fileName, save_data);
//     }
// }
/**
 * @brief database_table::on_comboBox_select_currentTextChanged 当前项被切换，此时需要重新载入对应的可选列
 * @param arg1
 */
void database_table::on_comboBox_select_currentTextChanged(const QString &arg1)
{
    qDebug() << "database_table::on_comboBox_select_currentTextChanged" << arg1;
    QStringList table_names;
    table_names << "" << table_list.value(arg1);

    ui->cb_channal1_param->clear();
    ui->cb_channal2_param->clear();
    ui->cb_channal3_param->clear();
    ui->cb_channal4_param->clear();

    ui->cb_channal1_param->addItems(table_names);
    ui->cb_channal2_param->addItems(table_names);
    ui->cb_channal3_param->addItems(table_names);
    if (table_names.size() > 0)
    {
        // 通道1选择带"A"的第一个内容
        int channel1Index = -1;
        for (int i = 1; i < table_names.size(); ++i) // 从索引1开始，跳过空字符串
        {
            if (table_names[i].contains("A", Qt::CaseInsensitive))
            {
                channel1Index = i;
                break;
            }
        }
        if (channel1Index != -1)
        {
            ui->cb_channal1_param->setCurrentIndex(channel1Index);
        }
        else if (table_names.size() > 1)
        {
            ui->cb_channal1_param->setCurrentIndex(1); // 默认选择第一个有效项
        }
    }
    ui->ckb_channal1->setChecked(true);
    ui->ckb_channal2->setChecked(true);
    ui->ckb_channal3->setChecked(true);
    ui->radioButton_history->setChecked(false);
    ui->radioButton_real->setChecked(true);
    on_radioButton_history_toggled(false);
    on_radioButton_real_toggled(true);
}

/**
 * @brief database_table::on_pushButton_quary_clicked 查询所配置的选择项
 */
void database_table::on_pushButton_quary_clicked()
{
    if (!table_list.contains(ui->comboBox_select->currentText()))
    {
        QMessageBox::information(this, "错误提示", "并不存在该柜，请检查config!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
        return;
    }

    // 获取当前日期和一个月前的日期
    QDateTime currentDateTime = QDateTime::currentDateTime();
    QDateTime oneMonthAgo = currentDateTime.addMonths(-1);

    // 设置时间为当天的开始和结束，避免秒级变化影响判断
    oneMonthAgo.setTime(QTime(0, 0, 0));        // 设置为当天0点0分0秒
    currentDateTime.setTime(QTime(23, 59, 59)); // 设置为当天23点59分59秒

    // 检查日期范围是否符合要求
    if (ui->dateTimeEdit_table_start->dateTime() < oneMonthAgo)
    {
        QMessageBox::information(this, "日期错误", "起始日期不允许在当日一个月前!", QMessageBox::Yes, QMessageBox::Yes);
        // 重置为一个月前的当天开始时间和当前时间
        ui->dateTimeEdit_table_start->setDateTime(oneMonthAgo);
        ui->dateTimeEdit_table_end->setDateTime(QDateTime::currentDateTime());
        return;
    }

    if (ui->dateTimeEdit_table_end->dateTime() > QDateTime::currentDateTime())
    {
        QMessageBox::information(this, "日期错误", "结束日期不允许大于当日!", QMessageBox::Yes, QMessageBox::Yes);
        // 重置为一个月前的当天开始时间和当前时间
        ui->dateTimeEdit_table_start->setDateTime(oneMonthAgo);
        ui->dateTimeEdit_table_end->setDateTime(QDateTime::currentDateTime());
        return;
    }

    if (ui->dateTimeEdit_table_start->dateTime() > ui->dateTimeEdit_table_end->dateTime())
    {
        QMessageBox::information(this, "错误提示", "日期不合理!", QMessageBox::Yes | QMessageBox::No, QMessageBox::Yes);
        return;
    }

    if (ui->radioButton_table->isChecked())
    {
        loadDataToTable(ui->comboBox_select->currentText(), ui->dateTimeEdit_table_start->dateTime(), ui->dateTimeEdit_table_end->dateTime(), ui->tableWidget_table);
    }

    if (ui->radioButton_chart->isChecked())
    {
        loadDataToChart(ui->comboBox_select->currentText());
    }
}
void database_table::createTablesFromMap()
{
    if (!sqlDataBase.isOpen())
    {
        qWarning() << "Database is not open!";
        return;
    }

    ui->comboBox_select->clear();

    // 遍历新的表定义
    QMap<QString, QStringList>::const_iterator it;
    for (it = table_list.constBegin(); it != table_list.constEnd(); ++it)
    {
        QString tableName = it.key();
        QStringList columns = it.value();

        ui->comboBox_select->addItem(tableName);

        // 跳过没有列的表
        if (columns.isEmpty())
        {
            qWarning() << "Skipping table" << tableName << "because it has no columns.";
            continue;
        }

        QString sql;

        // 检查数据库中是否已存在该表
        if (database_existing_tables.contains(tableName))
        {
            // 表已存在，检查是否有新列需要添加
            QStringList existingColumns = database_existing_tables.value(tableName);
            QStringList newColumns;

            // 找出新列
            for (const QString &column : columns)
            {
                if (!existingColumns.contains(column))
                {
                    newColumns << column;
                }
            }

            // 为每个新列添加 ALTER TABLE 语句
            for (const QString &newColumn : newColumns)
            {
                sql = QString("ALTER TABLE \"%1\" ADD COLUMN \"%2\" TEXT NOT NULL DEFAULT '--';")
                          .arg(tableName)
                          .arg(newColumn);

                QSqlQuery query(sqlDataBase);
                if (!query.exec(sql))
                {
                    qWarning() << "Failed to add column:" << sql << "Error:" << query.lastError().text();
                }
                else
                {
                    qDebug() << "Successfully added column" << newColumn << "to table" << tableName;
                }
            }
        }
        else
        {
            // 表不存在，创建新表
            QStringList columnDefs;
            columnDefs.append(QString("\"时间\" TEXT PRIMARY KEY"));
            for (const QString &column : columns)
            {
                columnDefs.append(QString("\"%1\" TEXT").arg(column));
            }

            sql = QString("CREATE TABLE IF NOT EXISTS \"%1\" (%2);")
                      .arg(tableName)
                      .arg(columnDefs.join(", "));

            QSqlQuery query(sqlDataBase);
            if (!query.exec(sql))
            {
                qWarning() << "Failed to create table:" << sql << "Error:" << query.lastError().text();
            }
            else
            {
                qDebug() << "Successfully created table" << tableName;
            }
        }
    }

    // 更新 table_list_last 以保持向后兼容
    // table_list_last = table_list;
}
// /**
//  * @brief database_table::createTablesFromMap 创建表和刷新列
//  */
// void database_table::createTablesFromMap()
// {
//     // 获取数据库连接，假设已配置好默认连接
//     if (!sqlDataBase.isOpen())
//     {
//         qWarning() << "Database is not open!";
//         return;
//     }

//     ui->comboBox_select->clear();
//     // 遍历 QMap
//     QMap<QString, QStringList>::const_iterator it;
//     for (it = table_list.constBegin(); it != table_list.constEnd(); ++it)
//     {
//         QString tableName = it.key();
//         QStringList columns = it.value();

//         ui->comboBox_select->addItem(tableName);

//         // 跳过没有列的表
//         if (columns.isEmpty())
//         {
//             qWarning() << "Skipping table" << tableName << "because it has no columns.";
//             continue;
//         }
//         QString sql;
//         // 判断是否要新增列
//         if (table_list_last.contains(tableName))
//         {
//             QStringList needAdd;
//             for (QString &item : columns)
//             {
//                 if (!table_list_last.value(tableName).contains(item))
//                 {
//                     needAdd << item;
//                     qDebug() << "add column addlist: " << item;
//                 }
//             }

//             if (!needAdd.isEmpty())
//             {
//                 for (QString &item : needAdd)
//                 {
//                     qDebug() << "add column: " << item;
//                     // 构建 CREATE TABLE 语句
//                     sql = QString("ALTER TABLE \"%1\" ADD COLUMN \"%2\" TEXT NOT NULL DEFAULT '--';")
//                               .arg(tableName) // 表名自动填充到 \"%1\" 中，形成 "表名"
//                               .arg(item);     // 列名自动填充到 \"%2\" 中，形成 "列名"
//                 }
//             }
//         }
//         else
//         {
//             // 处理列定义，每个列格式为 "列名 TEXT"
//             QStringList columnDefs;
//             columnDefs.append(QString("\"时间\" TEXT PRIMARY KEY"));
//             for (const QString &column : columns)
//             {
//                 // 使用双引号包裹列名，避免特殊字符问题
//                 columnDefs.append(QString("\"%1\" TEXT").arg(column));
//             }
//             // 构建 CREATE TABLE 语句
//             sql = QString("CREATE TABLE IF NOT EXISTS \"%1\" (%2);")
//                       .arg(tableName) // 表名用双引号包裹
//                       .arg(columnDefs.join(", "));
//         }
//         // 执行 SQL
//         // QSqlQuery query;
//         QSqlQuery query(sqlDataBase);
//         if (!query.exec(sql))
//         {
//             qWarning() << "run: " << sql << "error  reason " << ":" << query.lastError().text();
//         }
//         else
//         {
//             qDebug() << "Table" << sql << tableName << "created successfully.";
//         }
//     }
//     table_list_last = table_list;
// }

/**
 * @brief database_table::loadDataToTable 根据输入，加载对应表到tablewidget
 * @param tableName
 * @param startTime
 * @param endTime
 * @param tableWidget
 */
void database_table::loadDataToTable(const QString &tableName, const QDateTime &startTime, const QDateTime &endTime, QTableWidget *tableWidget)
{
    tableWidget->clear();        // 清除所有内容包括标题
    tableWidget->setRowCount(0); // 清除所有行
    // 准备 SQL 查询
    QSqlQuery query(sqlDataBase);
    query.prepare("SELECT * FROM '" + tableName + "' WHERE 时间 BETWEEN '" + startTime.toString("yyyy-MM-dd HH:mm:ss") + "' AND '" + endTime.toString("yyyy-MM-dd HH:mm:ss") + "'");
    // 执行查询
    if (!query.exec())
    {
        qDebug() << "执行" << query.lastQuery() << "失败：" << query.lastError().text();
        return;
    }
    else
    {
        qDebug() << "执行" << query.lastQuery() << "成功";
    }

    // 设置表格列数和标题
    tableWidget->setColumnCount(query.record().count());
    for (int i = 0; i < query.record().count(); ++i)
    {
        tableWidget->setHorizontalHeaderItem(i, new QTableWidgetItem(query.record().fieldName(i)));
    }

    // 填充数据
    int row = 0;
    while (query.next())
    {
        tableWidget->insertRow(row);
        for (int col = 0; col < query.record().count(); ++col)
        {
            QString value = query.value(col).toString();
            // 检查是否为数字，如果是则格式化为一位小数
            bool isNumber;
            double num = value.toDouble(&isNumber);
            if (isNumber)
            {
                value = QString::number(num, 'f', 1); // 格式化为一位小数
            }

            QTableWidgetItem *item = new QTableWidgetItem(value);
            item->setTextAlignment(Qt::AlignCenter); // 内容居中
            tableWidget->setItem(row, col, item);
        }
        row++;
    }

    // 隐藏行标题
    tableWidget->verticalHeader()->setVisible(false);

    // 设置列宽为表格总宽度的六分之一
    int totalWidth = tableWidget->viewport()->width();
    int columnWidth = totalWidth / 5;

    // 禁用自动拉伸模式
    tableWidget->horizontalHeader()->setSectionResizeMode(QHeaderView::Fixed);

    int columnCount = tableWidget->columnCount();
    for (int i = 0; i < columnCount; ++i)
    {
        tableWidget->setColumnWidth(i, columnWidth);
    }

    // 调整行高
    tableWidget->resizeRowsToContents(); // 行自适应
    // 设置表格为只读模式
    tableWidget->setSelectionMode(QAbstractItemView::NoSelection);
    tableWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);
    qDebug() << "Vertical scrollbar width:"
             << tableWidget->verticalScrollBar()->width();
}

/**
 * @brief database_table::loadDataToChart 加载所选择的曲线到曲线图里观看
 * @param tableName
 */
void database_table::loadDataToChart(const QString &tableName)
{
    // 第一步：查询该表所有数据，到map里，这里数据量较大
    /*先关闭示波器，清空所有当前的数据*/
    // if (ui->pb_open->text() == "Stop")
    // {
    //     ui->pb_open->setText("Start");
    //     ui->pb_open->setChecked(false); // 不允许打开
    //     ui->pb_open->setEnabled(false);
    //     killTimer(refreshTimer); // 关闭实时入列的定时器
    //     // emit sig_start_read_param("");
    // }

    /*清空所有数据和曲线*/
    m_dataCustomplot->clearGraphs();
    tracerGraph = NULL;
    tracerEnable = false;
    for (int i = 0; i < m_dataCustomplot->graphCount(); i++)
    {
        m_dataCustomplot->graph(i)->data().data()->clear();
        STRUCT_DATA_QUEUE &data = curve_store_map[i];
        data.data.clear();
        data.plotCounter = 0;
    }
    m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); // 重绘图像

    on_pb_down_set_released();
}

void database_table::on_radioButton_history_toggled(bool checked)
{

    if (checked)
    {
        killTimer(refreshTimer); // 挂壁实时显示
        if (ui->radioButton_chart->isChecked())
        {
            ui->stackedWidget_dis->setCurrentWidget(m_dataCustomplot);
            ui->widget_find->setEnabled(true);
            ui->widget_chart->setEnabled(true);
        }
        else
        {
            ui->stackedWidget_dis->setCurrentWidget(ui->page_table_2);
            ui->widget_find->setEnabled(true);
            ui->widget_chart->setEnabled(false);
        }
    }
}

void database_table::on_radioButton_real_toggled(bool checked)
{
    if (checked)
    {
        ui->stackedWidget_dis->setCurrentWidget(m_dataCustomplot);
        ui->widget_find->setEnabled(false);
        ui->widget_chart->setEnabled(true);
        m_dataCustomplot->clearGraphs();
        tracerGraph = NULL;
        tracerEnable = false;
        for (int i = 0; i < m_dataCustomplot->graphCount(); i++)
        {
            m_dataCustomplot->graph(i)->data().data()->clear();
            STRUCT_DATA_QUEUE &data = curve_store_map[i];
            data.data.clear();
            data.plotCounter = 0;
        }
        // m_dataCustomplot->replot(QCustomPlot::rpQueuedReplot); // 重绘图像

        on_pb_down_set_released();

        refreshTimer = startTimer(sample_rate); // 开启实时显示
        firstTimestamp = 0;
    }
}

void database_table::on_radioButton_chart_toggled(bool checked)
{
    if (checked)
    {
        ui->stackedWidget_dis->setCurrentWidget(m_dataCustomplot);
        ui->widget_find->setEnabled(true);
        ui->widget_chart->setEnabled(true);
    }
}

void database_table::on_radioButton_table_toggled(bool checked)
{
    if (checked)
    {
        ui->stackedWidget_dis->setCurrentWidget(ui->page_table_2);
        ui->widget_find->setEnabled(true);
        ui->widget_chart->setEnabled(false);
    }
}
void database_table::loadDataToMaps(const QString &tableName, const QStringList &columns, QMap<QString, QMap<QDateTime, QVariant>> &dataMaps)
{
    QDateTime startTime = ui->dateTimeEdit_table_start->dateTime();
    QDateTime endTime = ui->dateTimeEdit_table_end->dateTime();

    QString queryString = QString("SELECT \"时间\", %1 FROM \"%2\" WHERE \"时间\" BETWEEN '%3' AND '%4'")
                              .arg("\"" + columns.join("\", \"") + "\"")
                              .arg(tableName)
                              .arg(startTime.toString("yyyy-MM-dd HH:mm:ss"))
                              .arg(endTime.toString("yyyy-MM-dd HH:mm:ss"));
    // qDebug() << "SQL Query:" << queryString;
    QSqlQuery query(sqlDataBase);
    if (!query.prepare(queryString))
    {
        qDebug() << "SQL prepare error:" << query.lastError().text();
        return;
    }

    // 执行查询
    if (!query.exec())
    {
        qDebug() << "执行" << query.lastQuery() << "失败：" << query.lastError().text();
        return;
    }
    else
    {
        qDebug() << "执行" << query.lastQuery() << "成功";
    }

    // 处理查询结果
    while (query.next())
    {
        QDateTime datetime = query.value(0).toDateTime(); // 获取 datetime 字段
        for (int i = 0; i < columns.size(); ++i)
        {
            const QString &column = columns[i];
            QVariant value = query.value(i + 1);
            // 检查是否为数字，如果是则格式化为一位小数
            bool isNumber;
            double num = value.toDouble(&isNumber);
            if (isNumber)
            {
                dataMaps[column][datetime] = QString::number(num, 'f', 1); // 格式化为一位小数
            }
            else
            {
                dataMaps[column][datetime] = value;
            }
        }
        // QDateTime datetime = query.value(0).toDateTime(); // 获取 datetime 字段
        // for (int i = 0; i < columns.size(); ++i)
        // {
        //     const QString &column = columns[i];
        //     dataMaps[column][datetime] = query.value(i + 1); // 从第1列开始是数据字段
        // }
    }
}

void database_table::on_pb_dis_clicked()
{
    QPropertyAnimation *contentAnimation = new QPropertyAnimation(ui->widget_display, "geometry");
    contentAnimation->setDuration(300);
    contentAnimation->setEasingCurve(QEasingCurve::InOutQuad);
    QRect contentRect = ui->widget_display->geometry();

    if (isExpanded)
    {
        // 展开菜单栏
        contentRect.setX(menuWidth);
        ui->pb_dis->setProperty("expanded", true);
    }
    else
    {
        // 折叠菜单栏
        contentRect.setX(0);
        ui->pb_dis->setProperty("expanded", false);
    }

    contentAnimation->setStartValue(ui->widget_display->geometry());
    contentAnimation->setEndValue(contentRect);
    contentAnimation->start(QAbstractAnimation::DeleteWhenStopped);
    ui->widget_config->setVisible(isExpanded);
    isExpanded = !isExpanded;

    // 关键：刷新样式表
    ui->pb_dis->style()->unpolish(ui->pb_dis);
    ui->pb_dis->style()->polish(ui->pb_dis);
    ui->pb_dis->update();
}

void database_table::on_pb_full_clicked()
{
    if (!isFullScreen)
    {
        qDebug() << "enter full mode";
        // 进入全屏模式 - 创建一个全屏窗口来显示widget_full

        // 保存widget_full的原始信息
        originalParent = ui->widget_full->parentWidget();
        originalGeometry = ui->widget_full->geometry();
        originalLayout = ui->widget_full->parentWidget()->layout();

        if (originalLayout)
        {
            originalIndex = originalLayout->indexOf(ui->widget_full);
        }

        // 创建全屏窗口
        fullscreenWindow = new QWidget(nullptr, Qt::Window);
        fullscreenWindow->setAttribute(Qt::WA_StyledBackground);
        fullscreenWindow->setObjectName("MainWindow");
        fullscreenWindow->setWindowState(Qt::WindowFullScreen);
        fullscreenWindow->setLayout(new QVBoxLayout());
        fullscreenWindow->layout()->setContentsMargins(0, 0, 0, 0);
        // 使用与主窗口一致的样式表
        QFile file("./stylesheet/stylesheet.qss"); // 假设样式表文件路径
        if (file.open(QFile::ReadOnly))
        {
            QString styleSheet = QLatin1String(file.readAll());
            fullscreenWindow->setStyleSheet(styleSheet);
            file.close();
        }

        // 将widget_full添加到全屏窗口中
        ui->widget_full->setParent(fullscreenWindow);
        fullscreenWindow->layout()->addWidget(ui->widget_full);
        ui->widget_full->show();
        ui->widget_full->raise();
        ui->widget_full->setFocus();

        fullscreenWindow->showFullScreen();
        isFullScreen = true;
    }
    else
    {
        qDebug() << "exit full mode";
        // 退出全屏模式 - 将widget移回原位置
        if (fullscreenWindow && originalLayout)
        {
            // 从全屏窗口中移除widget_full
            if (fullscreenWindow->layout())
            {
                fullscreenWindow->layout()->removeWidget(ui->widget_full);
            }

            // 将widget_full重新添加到原始布局中
            ui->widget_full->setParent(originalParent);

            // 根据布局类型进行不同的处理
            if (QVBoxLayout *vboxLayout = qobject_cast<QVBoxLayout *>(originalLayout))
            {
                vboxLayout->insertWidget(originalIndex, ui->widget_full);
            }
            else if (QHBoxLayout *hboxLayout = qobject_cast<QHBoxLayout *>(originalLayout))
            {
                hboxLayout->insertWidget(originalIndex, ui->widget_full);
            }
            else if (QGridLayout *gridLayout = qobject_cast<QGridLayout *>(originalLayout))
            {
                // 对于网格布局，我们需要保存更多的信息，这里简化处理
                originalLayout->addWidget(ui->widget_full);
            }
            else
            {
                // 对于其他布局类型，直接添加
                originalLayout->addWidget(ui->widget_full);
            }

            ui->widget_full->show();
            ui->widget_full->raise();

            // 关闭并删除全屏窗口
            fullscreenWindow->close();
            delete fullscreenWindow;
            fullscreenWindow = nullptr;
        }
        else if (fullscreenWindow && originalParent)
        {
            // 如果无法通过布局恢复，尝试直接设置父窗口
            ui->widget_full->setParent(originalParent);
            ui->widget_full->setGeometry(originalGeometry);
            ui->widget_full->show();

            fullscreenWindow->close();
            delete fullscreenWindow;
            fullscreenWindow = nullptr;
        }
        isFullScreen = false;
    }
}
void database_table::on_cb_channal1_param_currentIndexChanged(int index)
{
}

void database_table::on_cb_channal1_param_currentTextChanged(const QString &arg1)
{
    // 检查通道1的选择是否包含"A"
    if (!arg1.contains("A", Qt::CaseInsensitive))
    {
        return; // 如果不包含"A"，则不执行后续操作
    }

    // 获取当前ComboBox中的所有选项
    QComboBox *channel1Combo = ui->cb_channal1_param;
    QStringList items;
    for (int i = 0; i < channel1Combo->count(); ++i)
    {
        items << channel1Combo->itemText(i);
    }

    // 去掉"A"后的基础字符串
    QString baseName = arg1;
    baseName.replace("A", "", Qt::CaseInsensitive);

    // 为通道2寻找匹配项（基础名+B）
    QString channel2Target = baseName + "B";
    int channel2Index = items.indexOf(channel2Target);
    if (channel2Index != -1)
    {
        ui->cb_channal2_param->setCurrentIndex(channel2Index);
    }
    else
    {
        ui->cb_channal2_param->setCurrentIndex(0); // 没找到则选择空项
    }

    // 为通道3寻找匹配项（基础名+C）
    QString channel3Target = baseName + "C";
    int channel3Index = items.indexOf(channel3Target);
    if (channel3Index != -1)
    {
        ui->cb_channal3_param->setCurrentIndex(channel3Index);
    }
    else
    {
        ui->cb_channal3_param->setCurrentIndex(0); // 没找到则选择空项
    }
    // 更新图表显示
    updateChartDisplay();
}

void database_table::on_cb_channal2_param_currentTextChanged(const QString &arg1)
{
    Q_UNUSED(arg1);
    // 更新图表显示
    updateChartDisplay();
}

void database_table::on_cb_channal3_param_currentTextChanged(const QString &arg1)
{
    Q_UNUSED(arg1);
    // 更新图表显示
    updateChartDisplay();
}
/**
 * @brief database_table::updateChartDisplay 更新图表显示
 * 当通道选择变化时，更新曲线图的图例和数据内容
 */
void database_table::updateChartDisplay()
{
    // 如果是历史数据模式，重新加载历史数据
    if (ui->radioButton_history->isChecked() && ui->radioButton_chart->isChecked())
    {
        loadDataToChart(ui->comboBox_select->currentText());
    }
    // 如果是实时数据模式，更新曲线设置
    else if (ui->radioButton_real->isChecked())
    {
        on_pb_down_set_released();
    }
}
void database_table::addIconToToolButton(QToolButton *toolButton, const QString &iconPath)
{
    // 创建布局
    QHBoxLayout *layout = new QHBoxLayout(toolButton);
    layout->setContentsMargins(5, 0, 5, 0);

    // 清除原有文本并重新添加
    QString text = toolButton->text();
    toolButton->setText("");

    QLabel *textLabel = new QLabel(text, toolButton);
    textLabel->setStyleSheet("border: none; background: transparent;");

    QLabel *iconLabel = new QLabel(toolButton);
    QPixmap pixmap(iconPath);
    if (!pixmap.isNull())
    {
        pixmap = pixmap.scaled(16, 16, Qt::KeepAspectRatio, Qt::SmoothTransformation);
        iconLabel->setPixmap(pixmap);
    }

    layout->addWidget(textLabel);
    layout->addStretch();
    layout->addWidget(iconLabel);

    toolButton->setLayout(layout);
}
